﻿using System;
using System.Linq;
using System.Security;
using InTheHand.Net;
using InTheHand.Net.Bluetooth;
using InTheHand.Net.Sockets;
using Oxage.CNC.Models;

namespace Oxage.CNC.Hardware
{
	public class BluetoothMachineController : MachineControllerBase
	{
		#region Private members
		private BluetoothModel model;
		#endregion

		#region Constructor
		public BluetoothMachineController()
		{
			model = new BluetoothModel();
		}
		#endregion

		#region Static methods
		/// <summary>
		/// Uploads a local file to the specified device via Bluetooth.
		/// </summary>
		/// <param name="deviceName">Friendly name of the remote device.</param>
		/// <param name="localPath">Path to a local file where file is read from.</param>
		/// <param name="remotePath">Path on the device where file should be saved to.</param>
		/// <param name="direct">A value indicating whether to establish direct communication (i.e. not waiting for device discovery)</param>
		/// <remarks>
		/// NOTE: This class currently provides only Obex file upload example for further development on Bluetooth module.
		/// </remarks>
		public static void Upload(string deviceName, string localPath, string remotePath, bool direct)
		{
			try
			{
				if (!BluetoothRadio.IsSupported)
				{
					Console.WriteLine("No bluetooth available on this machine.");
				}

				if (BluetoothRadio.PrimaryRadio.Mode == RadioMode.PowerOff)
				{
					BluetoothRadio.PrimaryRadio.Mode = RadioMode.Connectable;
				}

				Console.WriteLine("------------ My Information ------------");
				Console.WriteLine("Radio name: {0}", BluetoothRadio.PrimaryRadio.Name.ToString());
				Console.WriteLine("Radio mode: {0}", BluetoothRadio.PrimaryRadio.Mode.ToString());
				Console.WriteLine("----------------------------------------");

				BluetoothClient me = new BluetoothClient();
				Console.WriteLine("Discovering devices...");
				BluetoothDeviceInfo[] devices = (direct ? me.DiscoverDevices(10, true, true, false, false) : me.DiscoverDevices()); //Takes some time...

				if (devices != null && devices.Length > 0)
				{
					BluetoothDeviceInfo device = devices.FirstOrDefault(e => e.DeviceName == deviceName);
					if (device != null)
					{
						device.Update();
						device.Refresh();

						Console.WriteLine("Device name: {0}", device.DeviceName);
						Console.WriteLine("Last used: {0}", device.LastUsed);

						//Authenticate with the device
						if (!device.Authenticated)
						{
							//Use pin "0000" for authentication
							Console.WriteLine("Enter pin '0000' on the device.");
							if (!BluetoothSecurity.PairRequest(device.DeviceAddress, "0000"))
							{
								throw new SecurityException("Pairing request failed");
							}
						}

						device.SetServiceState(BluetoothService.ObexObjectPush, true);

						Uri uri = new Uri("obex://" + device.DeviceAddress + "/" + remotePath.Replace(@"\", "/"));

						ObexWebRequest req = new ObexWebRequest(uri);
						req.ReadFile(localPath);

						ObexWebResponse rsp = (ObexWebResponse)req.GetResponse(); //Works fine with Nokia Black
					}
					else
					{
						Console.WriteLine("Requested device does not exist!");
						Console.WriteLine("Available devices:");
						foreach (var info in devices)
						{
							Console.WriteLine(" * " + info.DeviceName);
						}
					}
				}
				else
				{
					Console.WriteLine("No device found!");
				}

				me.Close();
			}
			catch (Exception ex)
			{
				Console.WriteLine(ex.Message);
			}
			finally
			{
				Console.WriteLine("Completed!");
			}
		}
		#endregion

		#region IMachineController Members
		public override string Name
		{
			get { return "Bluetooth Machine Controller"; }
		}

		public override void Write(byte[] data)
		{
			throw new NotImplementedException();
		}
		#endregion
	}
}
